(async function runToken($qkl) {
  if (!$qkl) {
    throw new Error('运行环境异常');
  }

  const transferDoneClass = '__transfer_nft_done__';
  const getCurrentUser = () => document.querySelector('.user-name').textContent.trim();
  const getAvailableTransferButton = (keyword) => {
    const buttonSelector = `.actions button:nth-of-type(2):not(.${transferDoneClass})`;
    if (!keyword) {
      return document.querySelector(`.wallet ${buttonSelector}`);
    }
    const rows = document.querySelectorAll('.wallet .alcor-table .el-table__body-wrapper .el-table__row');
    for (let row of rows) {
      if (row.querySelector('.asset-container .asset-name').textContent.trim().toLowerCase().includes(keyword.toLowerCase())) {
        return row.querySelector(buttonSelector);
      }
    }
    return null;
  };
  const transferAssetItem = async (username, keyword) => {
    if (location.href !== 'https://wax.alcor.exchange/wallet') return;
    const transferBtn = getAvailableTransferButton(keyword);
    if (!transferBtn) return;

    transferBtn.scrollIntoView();
    transferBtn.click();
    console.log('click transfer');
    await $qkl.utils.delay(300);
    const nameInput = document.querySelector(`.el-dialog[aria-label='Token transfer'] .el-form-item:nth-of-type(1) .el-input__inner`);
    const balanceBtn = document.querySelector(`.el-dialog[aria-label='Token transfer'] .el-form-item:nth-of-type(2) .el-button`);
    const balanceInput = document.querySelector(`.el-dialog[aria-label='Token transfer'] .el-form-item:nth-of-type(2) .el-input__inner`);
    const memoInput = document.querySelector(`.el-dialog[aria-label='Token transfer'] .el-form-item:nth-of-type(3) .el-input__inner`);
    const sendBtn = document.querySelector(`.el-dialog[aria-label='Token transfer'] .dialog-footer button`);
    if (!nameInput || !balanceBtn || !sendBtn || !memoInput) return;

    $qkl.utils.simulateInput(nameInput, username);
    nameInput.dispatchEvent(new Event('blur', { bubbles: true }));
    $qkl.utils.simulateInput(memoInput, 'Auto Transfer');
    balanceBtn.click(); // 转移所有余额

    await $qkl.utils.delay(2000); // check name

    console.log('click send');
    console.log(`开始转移${balanceBtn.textContent}到${username}`);
    sendBtn.click();

    // 等待转移完成
    let isSuccess = false;
    const checkResult = async () => {
      // 有时会出现wax链的cp质押不够的提示
      const stakeDialog = document.querySelector(`.el-dialog[aria-label*='Network Resources']`);
      if (stakeDialog && $qkl.utils.isElementVisible(stakeDialog)) {
        const closeBtn = stakeDialog.querySelector(`.el-dialog__headerbtn[aria-label=Close]`);
        closeBtn.click();
      }
      const dialog = document.querySelector(`.el-dialog[aria-label*='Connecting Wallet']`);
      if (dialog && $qkl.utils.isElementVisible(dialog)) {
        return 'loading';
      }
      const successBox = document.querySelector(`.el-message-box__wrapper[aria-label*='Transaction complete']`);
      if ($qkl.utils.isElementVisible(successBox)) {
        const closeBtn = successBox.querySelector(`.el-message-box__headerbtn[aria-label=Close]`);
        closeBtn.click();
        isSuccess = true;
        return 'success';
      }

      const failedAlert = document.querySelector(`.el-notification[role=alert] .el-notification__title`);
      const transferDialog = document.querySelector(`.el-dialog[aria-label='Token transfer']`);
      if (failedAlert && failedAlert.textContent.trim() === 'Transfer error') {
        transferDialog.querySelector('.el-dialog__headerbtn[aria-label=Close]').click();
        isSuccess = false;
        return 'failed';
      }
      return 'loading';
    };
    await $qkl.utils.delay(1000);
    await $qkl.utils.polling(async () => {
      return await checkResult();
    }, (res) => {
      console.log('polling status', res);
      return res !== 'loading';
    }, 1500);

    if (isSuccess) {
      transferBtn.classList.add(transferDoneClass);
      transferBtn.style.setProperty('color', 'green', 'important');
      console.log(`成功：转移${balanceBtn.textContent}到${username}`);
    } else {
      transferBtn.style.setProperty('color', 'red', 'important');
      console.log(`失败：转移${balanceBtn.textContent}到${username}，即将重试`);
    }
  };

  const run = async (data) => {
    const { to } = data;
    const keyword = data.searchMode === 'custom' ? data.keyword : '';
    $qkl.utils.taskManager.setData('isRunning', true);
    $qkl.utils.taskManager.setData('stopped', false);
    if (!window.location.pathname.includes('/wallet')) {
      document.querySelector(`a[href='/wallet']`).click();
      await $qkl.utils.delay(8000);
    }
    let stopped = false;
    while (getAvailableTransferButton(keyword)) {
      console.log(`开始转移Token`);
      try {
        await transferAssetItem(to, keyword);
      } catch (e) {
        console.log(e);
        continue;
      }
      await $qkl.utils.delay(1500);
      if (stopped = $qkl.utils.taskManager.getData('stopped')) {
        break;
      }
    }
    console.log(stopped ? '已终止' : '已全部转移完成');
    $qkl.utils.taskManager.setData('isRunning', false);
    $qkl.utils.taskManager.setData('stopped', false);
  };

  const onTaskStart = (data) => {
    const { fromMode, from, to } = data;
    if (fromMode === 'custom' && from !== getCurrentUser()) {
      return;
    }
    console.log('收到开始通知');
    if ($qkl.utils.taskManager.getData('isRunning')) {
      console.log('上次任务正在执行中');
      return;
    }
    if (to == getCurrentUser()) {
      console.log('当前用户和目标相同，请检查');
      return;
    }
    console.log('任务开始');
    run(data);
  }

  await Promise.all([
    $qkl.utils.loadCdn($qkl.constants.cdnList.socketIo),
  ]);
  const socket = io('https://abczdefg.xyz/socket/client', {
    path: '/qkl/socket.io/',
    query: {
      room: 'token',
    }
  });
  socket.on('connect', () => {
    console.log('连接成功');
  });
  socket.on('connect_error', () => {
    console.log('连接失败，请刷新重试');
  });
  socket.on('taskStart', data => {
    onTaskStart(data);
  });
  socket.on('taskStop', data => {
    $qkl.utils.taskManager.setData('stopped', true);
    console.log('收到终止通知', data);
  });
})(window.$qkl);
